const Clutter = imports.gi.Clutter;
const Gdk     = imports.gi.Gdk;
const GtkClutter = imports.gi.GtkClutter;
const Gtk     = imports.gi.Gtk;
const Lang    = imports.lang;
const Mx      = imports.gi.Mx;
const OctopusClutterGtk = imports.gi.OctopusClutterGtk;
const Octopus = imports.gi.Octopus;
const Signals = imports.signals;

const ENTRYHEIGHT = 30;

function SearchPanel(container) {
	this._init(container);
}

SearchPanel.prototype = {
	_init: function (container) {
		this.searchPanelStack = new Mx.Stack ({ name: 'searchPanel-background',
		                                        x_align: Clutter.ActorAlign.FILL,
		                                        y_align: Clutter.ActorAlign.FILL,
		                                        y_expand: true,
		                                        reactive: true });
		container.add_child (this.searchPanelStack);
		this.searchPanelStack.connect('button-release-event', Lang.bind(this, this.onButtonReleaseEvent));

		this.searchPanelVBox = new Mx.BoxLayout ({ style_class: 'searchPanel-layout',
		                                           orientation: Mx.Orientation.VERTICAL,
		                                           x_align: Clutter.ActorAlign.FILL,
		                                           y_align: Clutter.ActorAlign.FILL });
		this.searchPanelStack.add_child (this.searchPanelVBox);
		//Name
		this.searchPanelNameLayout = new Mx.BoxLayout ({ orientation: Mx.Orientation.HORIZONTAL });
		this.searchPanelVBox.add_child (this.searchPanelNameLayout);
		this.searchPanelNameLabel = new Mx.Label ({ style_class: 'searchPanel-name-label',
		                                            text: 'Search' });
		this.searchPanelNameLayout.add_child (this.searchPanelNameLabel);

		this.searchPanelEntryLayout = new Mx.BoxLayout ({ orientation: Mx.Orientation.HORIZONTAL });
		this.searchPanelVBox.add_child (this.searchPanelEntryLayout);
		this.searchPanelEntryExpanderVBox = new Mx.BoxLayout ({ orientation: Mx.Orientation.VERTICAL });
		this.searchPanelEntryLayout.add_child (this.searchPanelEntryExpanderVBox);
		this.searchPanelGtkEntry = new Gtk.TextView ({ name: 'searchPanel-entry',
		                                               width_request: 600,
		                                               height_request: ENTRYHEIGHT,
		                                               wrap_mode: Gtk.WrapMode.NONE });
		this.eventBlocker = new OctopusClutterGtk.BlockReturnKeyPress ({ widget: this.searchPanelGtkEntry });
		this.searchPanelEntry = new GtkClutter.Actor ({ contents: this.searchPanelGtkEntry,
		                                                height: ENTRYHEIGHT });
		this.searchPanelEntryExpanderVBox.add_child (this.searchPanelEntry);
		this.searchPanelExpander = new Mx.Frame ({ style_class: 'searchPanel-expander',
		                                           height: 10,
		                                           reactive: true });
		this.searchPanelEntryExpanderVBox.add_child (this.searchPanelExpander);
		this.searchPanelExpander.connect ('button-release-event', Lang.bind(this, function (actor, event, user_data) {
			if ((event.get_button () == 1) && (event.get_click_count () == 1)) { //left mouse button
				this.searchPanelExpander.visible = false;
				this.searchPanelExpanderChecked.visible = true;
				this.searchPanelGtkEntry.height_request = 300;
				this.searchPanelEntry.height = 300;
				this.searchPanelGtkEntry.wrap_mode = Gtk.WrapMode.NONE;
			}
			return false; //propagate
		}));
		this.searchPanelExpanderIcon = new Mx.Icon ({ style_class: 'searchPanel-expander-icon',
		                                              x_align: Clutter.ActorAlign.CENTER,
		                                              y_align: Clutter.ActorAlign.CENTER });
		this.searchPanelExpander.add_child (this.searchPanelExpanderIcon);
		this.searchPanelExpanderChecked = new Mx.Frame ({ style_class: 'searchPanel-expander-checked',
		                                                  height: 10,
		                                                  reactive: true,
		                                                  visible: false });
		this.searchPanelEntryExpanderVBox.add_child (this.searchPanelExpanderChecked);
		this.searchPanelExpanderChecked.connect ('button-release-event', Lang.bind(this, function (actor, event, user_data) {
			if ((event.get_button () == 1) && (event.get_click_count () == 1)) { //left mouse button
				this.searchPanelExpander.visible = true;
				this.searchPanelExpanderChecked.visible = false;
				this.searchPanelGtkEntry.height_request = ENTRYHEIGHT;
				this.searchPanelEntry.height = ENTRYHEIGHT;
				this.searchPanelGtkEntry.wrap_mode = Gtk.WrapMode.WORD;
			}
			return false; //propagate
		}));
		this.searchPanelExpanderCheckedIcon = new Mx.Icon ({ style_class: 'searchPanel-expander-checked-icon',
		                                                     x_align: Clutter.ActorAlign.CENTER,
		                                                     y_align: Clutter.ActorAlign.CENTER });
		this.searchPanelExpanderChecked.add_child (this.searchPanelExpanderCheckedIcon);
		this.searchPanelEntryButtonFrame = new Mx.Frame ({ x_align: Clutter.ActorAlign.START,
		                                                   y_align: Clutter.ActorAlign.START });
		this.searchPanelEntryLayout.add_child (this.searchPanelEntryButtonFrame);
		this.searchPanelEntryButtonHBox = new Mx.BoxLayout ({ orientation: Mx.Orientation.HORIZONTAL });
		this.searchPanelEntryButtonFrame.add_child (this.searchPanelEntryButtonHBox);
		this.searchPanelClearButton = new Mx.Button ({ style_class: 'searchPanel-clear-button',
		                                               height: ENTRYHEIGHT, width: ENTRYHEIGHT });
		this.searchPanelEntryButtonHBox.add_child (this.searchPanelClearButton);
		this.searchPanelClearButton.connect ('clicked', Lang.bind(this, function () {
			this.searchPanelGtkEntry.buffer.text = "";
		}));
		this.searchPanelClearButton.connect ('enter-event', Lang.bind(this, function () {
			this.emit ('show-message-bar-text', "clear");
		}));
		this.searchPanelClearButton.connect ('leave-event', Lang.bind(this, function () {
			this.emit ('show-message-bar-text', "");
		}));
		this.searchPanelSearchButton = new Mx.Button ({ style_class: 'searchPanel-search-button',
		                                                height: ENTRYHEIGHT, width: ENTRYHEIGHT });
		this.searchPanelEntryButtonHBox.add_child (this.searchPanelSearchButton);
		this.searchPanelSearchButton.connect ('clicked', Lang.bind(this, function () {
			this.showSearchResult ();
		}));
		this.searchPanelSearchButton.connect ('enter-event', Lang.bind(this, function () {
			this.emit ('show-message-bar-text', "search");
		}));
		this.searchPanelSearchButton.connect ('leave-event', Lang.bind(this, function () {
			this.emit ('show-message-bar-text', "");
		}));
		//Properties
		this.searchPanelPropertiesLayout = new Mx.Table ({ style_class: 'searchPanel-property-layout',
		                                                   x_align: Clutter.ActorAlign.START,
		                                                   y_align: Clutter.ActorAlign.START });
		this.searchPanelVBox.add_child (this.searchPanelPropertiesLayout);
		//Properties 1. column
		this.searchPanelArtistButton = new Mx.Button ({ style_class: 'searchPanel-property-button',
		                                                label: 'artist:""' });
		this.searchPanelPropertiesLayout.insert_actor (this.searchPanelArtistButton, 0, 0);
		this.searchPanelArtistButton.connect ('clicked', Lang.bind(this, function () {
			this.searchPanelGtkEntry.buffer.insert_at_cursor ("artist:\"\"", -1);
		}));
		this.searchPanelAlbumButton = new Mx.Button ({ style_class: 'searchPanel-property-button',
		                                               label: 'album:""' });
		this.searchPanelPropertiesLayout.insert_actor (this.searchPanelAlbumButton, 1, 0);
		this.searchPanelAlbumButton.connect ('clicked', Lang.bind(this, function () {
			this.searchPanelGtkEntry.buffer.insert_at_cursor ("album:\"\"", -1);
		}));
		this.searchPanelTitleButton = new Mx.Button ({ style_class: 'searchPanel-property-button',
		                                               label: 'title:""' });
		this.searchPanelPropertiesLayout.insert_actor (this.searchPanelTitleButton, 2, 0);
		this.searchPanelTitleButton.connect ('clicked', Lang.bind(this, function () {
			this.searchPanelGtkEntry.buffer.insert_at_cursor ("title:\"\"", -1);
		}));
		this.searchPanelGenreButton = new Mx.Button ({ style_class: 'searchPanel-property-button',
		                                               label: 'genre:""' });
		this.searchPanelPropertiesLayout.insert_actor (this.searchPanelGenreButton, 3, 0);
		this.searchPanelGenreButton.connect ('clicked', Lang.bind(this, function () {
			this.searchPanelGtkEntry.buffer.insert_at_cursor ("genre:\"\"", -1);
		}));
		this.searchPanelInButton = new Mx.Button ({ style_class: 'searchPanel-property-button',
		                                            label: 'in:""' });
		this.searchPanelPropertiesLayout.insert_actor (this.searchPanelInButton, 4, 0);
		this.searchPanelInButton.connect ('clicked', Lang.bind(this, function () {
			this.searchPanelGtkEntry.buffer.insert_at_cursor ("in:\"\"", -1);
		}));
		//Properties 2. column
		this.searchPanelAndButton = new Mx.Button ({ style_class: 'searchPanel-property-button',
		                                             label: 'AND' });
		this.searchPanelPropertiesLayout.insert_actor (this.searchPanelAndButton, 0, 1);
		this.searchPanelAndButton.connect ('clicked', Lang.bind(this, function () {
			this.searchPanelGtkEntry.buffer.insert_at_cursor (" AND ", -1);
		}));
		this.searchPanelOrButton = new Mx.Button ({ style_class: 'searchPanel-property-button',
		                                            label: 'OR' });
		this.searchPanelPropertiesLayout.insert_actor (this.searchPanelOrButton, 1, 1);
		this.searchPanelOrButton.connect ('clicked', Lang.bind(this, function () {
			this.searchPanelGtkEntry.buffer.insert_at_cursor (" OR ", -1);
		}));
		this.searchPanelAsteriskButton = new Mx.Button ({ style_class: 'searchPanel-property-button',
		                                                  label: '*' });
		this.searchPanelPropertiesLayout.insert_actor (this.searchPanelAsteriskButton, 2, 1);
		this.searchPanelAsteriskButton.connect ('clicked', Lang.bind(this, function () {
			this.searchPanelGtkEntry.buffer.insert_at_cursor ("*", -1);
		}));
		this.searchPanelQuestionMarkButton = new Mx.Button ({ style_class: 'searchPanel-property-button',
		                                                      label: '?' });
		this.searchPanelPropertiesLayout.insert_actor (this.searchPanelQuestionMarkButton, 3, 1);
		this.searchPanelQuestionMarkButton.connect ('clicked', Lang.bind(this, function () {
			this.searchPanelGtkEntry.buffer.insert_at_cursor ("?", -1);
		}));
		//Properties 3. column
		this.searchPanelGroupByAlbumLayout = new Mx.BoxLayout ({ orientation: Mx.Orientation.HORIZONTAL });
		this.searchPanelPropertiesLayout.insert_actor (this.searchPanelGroupByAlbumLayout, 0, 2);
		this.searchPanelGroupByAlbumButton = new Mx.Button ({ style_class: 'searchPanel-group-button',
		                                                      height: 20, width: 20,
		                                                      is_toggle: true });
		this.searchPanelGroupByAlbumLayout.add_child (this.searchPanelGroupByAlbumButton);
		this.searchPanelGroupByAlbumLabel = new Mx.Label ({ style_class: 'searchPanel-group-label',
		                                                    text: 'group by album' });
		this.searchPanelGroupByAlbumLayout.add_child (this.searchPanelGroupByAlbumLabel);

		this.searchPanelOverlay = new Mx.Frame ({ name: 'searchPanel-overlay' });
		this.searchPanelStack.add_child (this.searchPanelOverlay);

		//create model
		this.medialibSearch = new Octopus.MedialibSearch ();
	},

	onButtonReleaseEvent: function (actor, event, user_data) {
		this.searchPanelGtkEntry.grab_focus ();
		this.emit ('grab-key-focus');
	},

	showSearchResult: function () {
		let searchText = this.searchPanelGtkEntry.buffer.text;
		if (searchText.trim ().length == 0) return;
		this.medialibSearch.searchquery = searchText.replace ('\n', ' ');
		this.medialibSearch.set_grouped_by_album (this.searchPanelGroupByAlbumButton.toggled);
		this.loadedSignalId =
		this.medialibSearch.connect ('loaded', Lang.bind(this, function () {
			this.medialibSearch.disconnect (this.loadedSignalId);
			this.addSignalId =
			this.medialibSearch.connect ('add', Lang.bind (this, function (/*IMedialibQuery*/collectionlist_model, /*IMedialibInfo*/collection_model) {
				this.medialibSearch.disconnect (this.addSignalId);
				this.emit ('tracklist-panel-show', collection_model);
			}));
			this.medialibSearch.request_data ();
		}));
		this.medialibSearch.load ();
	},

	onKeyPressEvent: function (/*uint*/keyval, /*string*/str, /*Gdk.ModifierType*/modifiers) {
		if (   ((modifiers & Gdk.ModifierType.SHIFT_MASK) != Gdk.ModifierType.SHIFT_MASK) 
		    && (keyval == Gdk.KEY_Return)) {
			this.showSearchResult ();
		}
	}

};

Signals.addSignalMethods(SearchPanel.prototype);
